import MsgCenter from '../util/socket/msg/MsgCenter'
import YfWebSocket from '../util/socket/socket'
import YfWx from '../util/wx'
import store from '../store'
import request from '../util/request'
import {getToken} from "../util/qiniu";
import Qiniu from '../util/qiniu'
import * as types from '../store/types'
import MsgSession from "../util/socket/msg/MsgSession";

class ChatHandler {


    constructor() {
        this.currentVoiceMsgText = null  //正在播放的语音组件
    }


    initApp = async () => {
        console.log("socket==========")
        // await this.initWxConfig() //微信配置完毕
        await YfWebSocket.initWebSocket(process.env.VUE_APP_SOCKETURL, this._onMsgHandler, this._onOpenHandler) //聊天初始化完毕


        Qiniu.init(process.env.VUE_APP_DOMAIN + '/dmz/qiniu/token')

    }


    /**
     * 初始化微信配置
     */
    initWxConfig = async (debug) => {
        if (process.env.NODE_ENV === 'development') {
            return
        }
        let url = store.getters.currentUrl
        console.log(window.__wxjs_is_wkwebview + '====')
        if (window.__wxjs_is_wkwebview) {//ios
            url = store.getters.firstUrl
            console.log(url + 'firstUrl')
        } else {
            url = process.env.VUE_APP_CLIENT + url
        }
        url = url.split("#")[0]

        //当前路由地址
        let configUrl = '/api/sdk/config';
        let res = await request.get(configUrl, {params: {url: url}})
        let config = res.data
        //先获取配置
        await YfWx.wxConfig(config, debug ? true : false)
    }

    /**
     * 设置当前正在聊天的用户
     * @param chatUserId
     */
    setNowChatUser = (userId, chatType) => {
        //配置消息中心
        MsgCenter.initChatUser(store.getters.userId, userId, chatType)
    }


    /**
     * 发送文本消息
     * @param content
     * @param chatType
     */
    sendTextMsg = (content) => {
        let msgProto = MsgCenter.createTextMsgProto(content);
        let msgBytes = MsgCenter.serializeBinary(msgProto)
        //本地处理
        this._handleChattingMsg(msgProto)
        YfWebSocket.sendMsg(msgBytes)
    }

    /**
     * 发送图片避免回调地狱
     * @param chatType
     * @returns {Promise<void>}
     */
    sendImageMsg = async () => {
        YfWx.chooseImage().then(localIds => {
            localIds.forEach((localId) => {
                YfWx.uploadImage(localId).then((serverId) => {
                    //发送
                    let msgProto = MsgCenter.createImageMsgProto(localId, serverId)
                    YfWebSocket.sendMsg(MsgCenter.serializeBinary(msgProto))
                    //本地处理
                    this._handleChattingMsg(msgProto)
                })
            })
        })
    }

    /**
     * H5的方式获取图片
     * @returns {Promise<void>}
     */
    sendImageMsgH5 = async (file) => {
        //自己渲染就用自己的本地图
        let msgProto = MsgCenter.createImageMsgProto(file, '')
        //先处理
        this._handleChattingMsg(msgProto)
        let key =await Qiniu.uploadBase64Img(file)
        msgProto.setServerid(key)
        msgProto.setLocalid('')
        YfWebSocket.sendMsg(MsgCenter.serializeBinary(msgProto))
    }

    //发送连接消息
    _sendConnectMsg = () => {
        let msgProto = MsgCenter.createConnectMsg()
        YfWebSocket.sendMsg(MsgCenter.serializeBinary(msgProto))
    }

    //发送心跳消息
    _sendHeartMsg = () => {
        let msgProto = MsgCenter.createHeartMsg()
        YfWebSocket.sendMsg(MsgCenter.serializeBinary(msgProto))
    }


    /**
     * 开始录音
     */
    startRecord = () => {
        //停止当前声音播放
        this._stopCurrentMsgVoiceText()
        this.startTime = new Date().getTime()
        YfWx.startRecord();
    }

    /**
     * 停止当前声音组件的活动
     * @private
     */
    _stopCurrentMsgVoiceText = () => {
        if (this.currentVoiceMsgText) {
            YfWx.stopVoice(this.currentVoiceMsgText.Msg.localid)
            this.currentVoiceMsgText.onPlay = false
        }
    }


    /**
     * 单纯的取消
     */
    cancelRecord = () => {
        YfWx.stopRecord();
    }

    /**
     * 发送语音
     * @param chatType
     */
    sendVoiceMsg = () => {
        let recordTime = Math.ceil((new Date().getTime() - this.startTime) / 1000)
        YfWx.stopRecord().then(localId => {
            let msgProto = MsgCenter.createVoiceMsg(recordTime, localId, '')
            //先渲染 渲染的时候没有serverId的
            this._handleChattingMsg(msgProto)
            //去掉localId 设置serverId 上传并发送
            YfWx.uploadVoice(localId).then((serverId) => {
                msgProto.setLocalid('');
                msgProto.setServerid(serverId)
                YfWebSocket.sendMsg(MsgCenter.serializeBinary(msgProto))
            })
        })
    }


    /**
     * 播放声音
     * @param MsgText
     */
    playVoice = async (msgText) => {
        //判断是否点击的是同一个
        if (this.currentVoiceMsgText && this.currentVoiceMsgText.Msg.guid == msgText.Msg.guid) {
            if (this.currentVoiceMsgText.onPlay) { //如果还在播放
                //停止播放
                this._stopCurrentMsgVoiceText()
            } else {
                this.currentVoiceMsgText.onPlay = true
                //播放语音
                YfWx.playVoice(this.currentVoiceMsgText.Msg.localid)
            }
        } else {
            if (this.currentVoiceMsgText) { //点击了另外一个
                //停止之前的
                this._stopCurrentMsgVoiceText()
            }
            let localId = msgText.Msg.localid
            if (!localId) { //下载localId
                localId = await YfWx.downloadVoice(msgText.Msg.serverid)
                msgText.Msg.local = localId
            }
            //播放点击的
            msgText.onPlay = true
            YfWx.playVoice(localId)
            //更新这次点击
            this.currentVoiceMsgText = msgText
        }
    }

    onVoicePlayEnd = () => {
        YfWx.onVoicePlayEnd().then(localId => {
            console.log(localId + 'bofang jieshu asd ')
            if (this.currentVoiceMsgText.onPlay) {
                this.currentVoiceMsgText.onPlay = false
            }
            this.onVoicePlayEnd()//重新注册
        })
    }


    /**
     * socket 接收到消息后的回调
     * @private
     */
    _onMsgHandler = (data) => {
        let msgProto = MsgCenter.deserializeBinary(data)
        this._handleChattingMsg(msgProto)
    }

    /**
     * socket启动之后
     * @param data
     * @private
     */
    _onOpenHandler = () => {
        let fromUserId = store.getters.userId
        //初始化消息中心
        MsgCenter.initChatUser(fromUserId, MsgCenter.toUserId, MsgCenter.nowChatType)
        //发送连接消息
        this._sendConnectMsg()
        //发送心跳
        this._sendHeartMsg()
    }

    /**
     *
     * 异步不阻塞 等待消息消息完成
     * 处理及时聊天的消息
     * 流程
     * 1-存储到本地
     * 2-加到Vuex及时聊天 nowMsg 进行渲染
     * 3-如果与人正在聊天 存储到Vuex进行渲染
     * 4-渲染到最近聊天
     * @param msgProto
     */
    _handleChattingMsg = async (msgProto) => {
        let msgObject = msgProto.toObject()
        if (msgProto.getType() == MsgCenter.MsgType.CONNECT || msgProto.getType() == MsgCenter.MsgType.KEEPALIVE) {
            return
        }
        let sessionId = MsgCenter.getChatUserId(msgObject, store.getters.userId)
        //更新msgMap
        //加入消息ma
        store.commit(types.UPDATE_MSG_MAP, {
            type: 'push',
            msg: msgObject,
            sessionId: sessionId
        })
        let isRead = false
        //如果正在与此人聊天 =
        if (MsgCenter.toUserId) {
            isRead = true //如果正在与此人聊天消息已读
            //加入当前消息列表
            store.commit(types.UPDATE_CURRENT_MSG_LIST, {
                type: 'push',
                msg: msgObject
            })
        }
        let session = MsgSession.msgToSession(msgObject, !isRead, sessionId)
        //下载session信息
        store.dispatch('downLoadSessionInfo', [session])
        //加入一条session
        store.commit(types.UPDATE_SESSION_MAP, {
            type: 'push',
            msgSession: session
        })
    }


    /**
     * 渲染将要聊天对象的消息记录
     */
    handleToChatMsgRecord = () => {
        let sessionId = MsgCenter.toUserId
        let chatType = MsgCenter.nowChatType

        // 调用concat TODO 根据消息的数量选择是否需要加载
        store.commit(types.UPDATE_CURRENT_MSG_LIST, {
            type: 'init',
            sessionId: sessionId
        })
        //初始化的时候加载
        let init = true
        store.dispatch('downLoadCurrentUserMsgRecord', {sessionId, chatType, init})
    }


    /**
     * 处理线上的消息  线上的消息字段名跟本地的字段名有些不同 需要处理
     * 等待所有的消息处理完
     * @private
     */
    msgToLowerCase = (msgList) => {
        for (let i = 0, len = msgList.length; i < len; i++) {
            let msg = msgList[i]
            for (let key in msg) {
                //大写key转小写
                let lowerKey = key.toLocaleLowerCase();
                if (lowerKey == key) {
                    continue;
                }
                msg[lowerKey] = msg[key]
                //删除大写
                delete(msg[key])
            }
        }
    }


    share(title, desc, link, imageUrl) {
        YfWx.share(title, desc, link, imageUrl)
    }

    /**
     * 这是是否是条发送消息
     * @param msg
     */
    isSend(msg) {
        if (store.state.user.userId == msg.fromuserid) {
            return true
        } else {
            return false
        }
    }

    getVoiceExtra(msg) {
        if (msg.type !== MsgCenter.MsgType.VOICE) {
            return {}
        }
        let content = msg.content
        content = JSON.parse(content)
        return {
            time: content.time
        }
    }

    getUserInfo(userId) {
        let userInfo = store.getters.userInfoMap[userId]
        if (userInfo) {
            return userInfo
        } else {
            //TODO 修改默认头像
            return {
                name: '未知',
                avatar: 'https://ojpbly1un.qnssl.com/gogopher.jpg'
            }
        }
    }

    getGroupInfo(groupId) {
        let groupInfo = store.getters.groupInfoMap[groupId]
        if (groupInfo) {
            return groupInfo
        } else {
            //TODO 修改默认头像
            return {
                name: '未知',
                avatar: 'logo.jpeg'
            }
        }
    }

    pay(param) {
        return YfWx.pay(param)
    }


}

export default new ChatHandler()